home *** CD-ROM | disk | FTP | other *** search
/ NeXT Education Software Sampler 1992 Fall / NeXT Education Software Sampler 1992 Fall.iso / Programming / Source / winterp-1.13 / src-server / xlisp / xldbug.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-04  |  9.4 KB  |  342 lines

  1. /* -*-C-*-
  2. ********************************************************************************
  3. *
  4. * File:         xldebug.c
  5. * RCS:          $Header: xldbug.c,v 1.6 91/03/24 22:24:31 mayer Exp $
  6. * Description:  xlisp debugging support
  7. * Author:       David Michael Betz; Niels Mayer
  8. * Created:      
  9. * Modified:     Fri Oct  4 03:38:15 1991 (Niels Mayer) mayer@hplnpm
  10. * Language:     C
  11. * Package:      N/A
  12. * Status:       X11r5 contrib tape release
  13. *
  14. * WINTERP Copyright 1989, 1990, 1991 Hewlett-Packard Company (by Niels Mayer).
  15. * XLISP version 2.1, Copyright (c) 1989, by David Betz.
  16. *
  17. * Permission to use, copy, modify, distribute, and sell this software and its
  18. * documentation for any purpose is hereby granted without fee, provided that
  19. * the above copyright notice appear in all copies and that both that
  20. * copyright notice and this permission notice appear in supporting
  21. * documentation, and that the name of Hewlett-Packard and David Betz not be
  22. * used in advertising or publicity pertaining to distribution of the software
  23. * without specific, written prior permission.  Hewlett-Packard and David Betz
  24. * make no representations about the suitability of this software for any
  25. * purpose. It is provided "as is" without express or implied warranty.
  26. *
  27. * HEWLETT-PACKARD AND DAVID BETZ DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
  28. * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
  29. * IN NO EVENT SHALL HEWLETT-PACKARD NOR DAVID BETZ BE LIABLE FOR ANY SPECIAL,
  30. * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  31. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  32. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  33. * PERFORMANCE OF THIS SOFTWARE.
  34. *
  35. * See ./winterp/COPYRIGHT for information on contacting the authors.
  36. * Please send modifications, improvements and bugfixes to mayer@hplabs.hp.com
  37. * Post XLISP-specific questions/information to the newsgroup comp.lang.lisp.x
  38. *
  39. ********************************************************************************
  40. */
  41. static char rcs_identity[] = "@(#)$Header: xldbug.c,v 1.6 91/03/24 22:24:31 mayer Exp $";
  42.  
  43. #ifdef WINTERP
  44. #include <X11/Intrinsic.h>
  45. #endif
  46. #include "xlisp.h"
  47.  
  48. /* external variables */
  49. extern int xldebug;
  50. extern int xlsample;
  51. extern LVAL s_debugio,s_unbound;
  52. extern LVAL s_tracenable,s_tlimit,s_breakenable;
  53. extern LVAL true;
  54. extern char buf[];
  55.  
  56. /* external routines */
  57. extern char *malloc();
  58.  
  59. /* forward declarations */
  60. /* FORWARD LVAL stacktop(); */ /* NPM: commented this out since it is not defined anywhere */
  61.  
  62. /* xlabort - xlisp serious error handler */
  63. xlabort(emsg)
  64.   char *emsg;
  65. {
  66.     xlsignal(emsg,s_unbound);
  67.     xlerrprint("error",NULL,emsg,s_unbound);
  68.     xlbrklevel();
  69. }
  70.  
  71. /* xlbreak - enter a break loop */
  72. xlbreak(emsg,arg)
  73.   char *emsg; LVAL arg;
  74. {
  75.     breakloop("break","return from BREAK",emsg,arg,TRUE);
  76. }
  77.  
  78. /* xlfail - xlisp error handler */
  79. xlfail(emsg)
  80.   char *emsg;
  81. {
  82.     xlerror(emsg,s_unbound);
  83. }
  84.  
  85. /* xlerror - handle a fatal error */
  86. xlerror(emsg,arg)
  87.   char *emsg; LVAL arg;
  88. {
  89.     if (getvalue(s_breakenable) != NIL)
  90.     breakloop("error",NULL,emsg,arg,FALSE);
  91.     else {
  92.     xlsignal(emsg,arg);
  93.     xlerrprint("error",NULL,emsg,arg);
  94.     xlbrklevel();
  95.     }
  96. }
  97.  
  98. /* xlcerror - handle a recoverable error */
  99. xlcerror(cmsg,emsg,arg)
  100.   char *cmsg,*emsg; LVAL arg;
  101. {
  102.     if (getvalue(s_breakenable) != NIL)
  103.     breakloop("error",cmsg,emsg,arg,TRUE);
  104.     else {
  105.     xlsignal(emsg,arg);
  106.     xlerrprint("error",NULL,emsg,arg);
  107.     xlbrklevel();
  108.     }
  109. }
  110.  
  111. /* xlerrprint - print an error message */
  112. xlerrprint(hdr,cmsg,emsg,arg)
  113.   char *hdr,*cmsg,*emsg; LVAL arg;
  114. {
  115.     /* print the error message */
  116.     sprintf(buf,"%s: %s",hdr,emsg);
  117.     errputstr(buf);
  118.  
  119.     /* print the argument */
  120.     if (arg != s_unbound) {
  121.     errputstr(" - ");
  122.     errprint(arg);
  123.     }
  124.  
  125.     /* no argument, just end the line */
  126.     else
  127.     errputstr("\n");
  128.  
  129.     /* print the continuation message */
  130.     if (cmsg) {
  131.     sprintf(buf,"if continued: %s\n",cmsg);
  132.     errputstr(buf);
  133.     }
  134. }
  135.  
  136. #ifdef WINTERP
  137. /*
  138.  * This version of breakloop() works with server in winterp.c. It allows you
  139.  * to be in the breakloop while X Events and Xlisp server requests to be
  140.  * processed.
  141.  */
  142. LOCAL int breakloop(hdr,cmsg,emsg,arg,cflag)
  143.      char *hdr,*cmsg,*emsg; LVAL arg; int cflag;
  144. {
  145.   extern int read_eval_print_just_called; /* from winterp.c */
  146.   extern int lisp_reader_hit_eof; /* from winterp.c */
  147.   extern XtAppContext app_context; /* from winterp.c */
  148.   LVAL expr,val;
  149.   CONTEXT cntxt;
  150.   int type;
  151.   XEvent event;
  152.  
  153.   xlerrprint(hdr,cmsg,emsg,arg); /* print the error message */
  154.  
  155.   /* flush the input buffer --  needed if using (read)/(read-line) from stdin */
  156.   xlflush();
  157.  
  158.   if (getvalue(s_tracenable)) {    /* do the back trace */
  159.     val = getvalue(s_tlimit);
  160.     xlbaktrace(fixp(val) ? (int)getfixnum(val) : -1);
  161.   }
  162.   xlsave1(expr);        /* protect some pointers */
  163.   ++xldebug;            /* increment the debug level */
  164.  
  165.   read_eval_print_just_called = TRUE; /* special initial cond */
  166.   lisp_reader_hit_eof = FALSE;
  167.  
  168.   /* debug command processing loop -- note similarity to loop winterp.c:main() */
  169.   xlbegin(&cntxt,CF_BRKLEVEL|CF_CLEANUP|CF_CONTINUE,true);
  170.   for (type = 0; type == 0; ) {
  171.     /* 
  172.      * We need to setup a new error return only after each time that an XLISP 
  173.      * evaluation occurs. Therefore, we check for read_eval_print_just_called 
  174.      * (which is set by Read_Eval_Print()) and then clear it once the setjmp() 
  175.      * has been done. This avoids setting up an error return for each X event
  176.      * being processed in this loop. 
  177.      */
  178.     if (read_eval_print_just_called) { /* set in winterp.c:Read_Eval_Print callback */
  179.       read_eval_print_just_called = FALSE;
  180.       if (lisp_reader_hit_eof) {    /* set in winterp.c:Read_Eval_Print callback */
  181.     type = CF_CLEANUP;
  182.     break;
  183.       }
  184.       if (type = setjmp(cntxt.c_jmpbuf)) /* setup the continue trap */
  185.     switch (type) {
  186.     case CF_CLEANUP:
  187.       continue;
  188.     case CF_BRKLEVEL:
  189.       type = 0;
  190.       break;
  191.     case CF_CONTINUE:
  192.       if (cflag) {
  193.         dbgputstr("[ continue from break loop ]\n");
  194.         continue;
  195.       }
  196.       else 
  197.         xlabort("this error can't be continued");
  198.     }
  199.       sprintf(buf, "XLisp-Breakloop-Level-%d> ", xldebug); /* print a "prompt" */
  200.       dbgputstr(buf);
  201.       fflush(stdout); fflush(stderr); /* otherwise output won't happen while blocked in XtAppNextEvent() */
  202.     }
  203.  
  204.     /*
  205.      * XtAppNextEvent() waits for Xevents, and while it is waiting, it will
  206.      * process inputs added via AtAppAddInput() or XtAppAddWorkProc(). Lisp 
  207.      * server input will cause Read_Eval_Print() to get called, and that
  208.      * procedure sets the globals lisp_reader_hit_eof and 
  209.      * read_eval_print_just_called. Read_Eval_Print() sends a bogus 
  210.      * XAnyEvent (event.type == 0) so as to force XtAppNextEvent() to return; 
  211.      * otherwise it would only return if a lisp evaluation caused X events 
  212.      * to be generated, which means that XLISP error returns for non-X 
  213.      * evaluations wouldn't get set up properly.
  214.      *
  215.      * XtDispatchEvent() will dispatch the actions from the events gathered
  216.      * by XtAppNextEvent(). Note that XtAppNextEvent() ignores the aforementioned
  217.      * bogus events: "if (event->type == 0) return;"
  218.      */
  219.     XtAppNextEvent(app_context, &event);
  220.     XtDispatchEvent(&event);
  221.   }
  222.   xlend(&cntxt);
  223.  
  224.   --xldebug;            /* decrement the debug level */
  225.   xlpop();            /* restore the stack */
  226.   if (type == CF_CLEANUP)    /* check for aborting to the previous level */
  227.     xlbrklevel();
  228. }
  229.  
  230. #else
  231.  
  232. /* breakloop - the debug read-eval-print loop */
  233. LOCAL int breakloop(hdr,cmsg,emsg,arg,cflag)
  234.   char *hdr,*cmsg,*emsg; LVAL arg; int cflag;
  235. {
  236.     LVAL expr,val;
  237.     CONTEXT cntxt;
  238.     int type;
  239.  
  240.     /* print the error message */
  241.     xlerrprint(hdr,cmsg,emsg,arg);
  242.  
  243.     /* flush the input buffer */
  244.     xlflush();
  245.  
  246.     /* do the back trace */
  247.     if (getvalue(s_tracenable)) {
  248.     val = getvalue(s_tlimit);
  249.     xlbaktrace(fixp(val) ? (int)getfixnum(val) : -1);
  250.     }
  251.  
  252.     /* protect some pointers */
  253.     xlsave1(expr);
  254.  
  255.     /* increment the debug level */
  256.     ++xldebug;
  257.  
  258.     /* debug command processing loop */
  259.     xlbegin(&cntxt,CF_BRKLEVEL|CF_CLEANUP|CF_CONTINUE,true);
  260.     for (type = 0; type == 0; ) {
  261.  
  262.     /* setup the continue trap */
  263.     if (type = setjmp(cntxt.c_jmpbuf))
  264.         switch (type) {
  265.         case CF_CLEANUP:
  266.         continue;
  267.         case CF_BRKLEVEL:
  268.         type = 0;
  269.         break;
  270.         case CF_CONTINUE:
  271.         if (cflag) {
  272.             dbgputstr("[ continue from break loop ]\n");
  273.             continue;
  274.         }
  275.         else xlabort("this error can't be continued");
  276.         }
  277.  
  278.     /* print a prompt */
  279.     sprintf(buf,"%d> ",xldebug);
  280.     dbgputstr(buf);
  281.  
  282.     /* read an expression and check for eof */
  283.     if (!xlread(getvalue(s_debugio),&expr,FALSE)) {
  284.         type = CF_CLEANUP;
  285.         break;
  286.     }
  287.  
  288.     /* save the input expression */
  289.     xlrdsave(expr);
  290.  
  291.     /* evaluate the expression */
  292.     expr = xleval(expr);
  293.  
  294.     /* save the result */
  295.     xlevsave(expr);
  296.  
  297.     /* print it */
  298.     dbgprint(expr);
  299.     }
  300.     xlend(&cntxt);
  301.  
  302.     /* decrement the debug level */
  303.     --xldebug;
  304.  
  305.     /* restore the stack */
  306.     xlpop();
  307.  
  308.     /* check for aborting to the previous level */
  309.     if (type == CF_CLEANUP)
  310.     xlbrklevel();
  311. }
  312.  
  313. #endif
  314.  
  315. /* baktrace - do a back trace */
  316. xlbaktrace(n)
  317.   int n;
  318. {
  319.     LVAL *fp,*p;
  320.     int argc;
  321.     for (fp = xlfp; (n < 0 || n--) && *fp; fp = fp - (int)getfixnum(*fp)) {
  322.     p = fp + 1;
  323.     errputstr("Function: ");
  324.     errprint(*p++);
  325.     if (argc = (int)getfixnum(*p++))
  326.         errputstr("Arguments:\n");
  327.     while (--argc >= 0) {
  328.         errputstr("  ");
  329.         errprint(*p++);
  330.     }
  331.     }
  332. }
  333.  
  334. /* xldinit - debug initialization routine */
  335. xldinit()
  336. {
  337.     xlsample = 0;
  338.     xldebug = 0;
  339. }
  340.  
  341.